package heuristicFunctions;

import domain.PacmanBoard;
import aima.core.search.framework.HeuristicFunction;
import aima.core.util.datastructure.XYLocation;

public class MurenHeuristiek implements HeuristicFunction  {

	@Override
	public double h(Object state) {
		//het idee erachter is dat we rekening houden met de omliggende muren
		//het valt buiten de map== niet bestaande lokaties worden opgevuld met muren
		// we geven terug het aantal muren * vogelvlucht(Manhattan)
		final PacmanBoard board = (PacmanBoard) state;
		final XYLocation actor = board.getPacmanLocation();
		final XYLocation finish = board.getFinishLocation();
		double aantalmuren=0;
		double murenCheck=0;
		double aantalLegeVakjes=0;
		char[][] map= board.getMap();
		char[][] muren= new char[7][7];

		//aantal muren op het bord
		for(int row=0;row<map.length;row++){
			for(int col=0;col<map[row].length;col++){
				if(map[row][col]=='%')
					murenCheck++;
			}
		}

		int RowLength=map.length;
		int ColLength=map[0].length;
		//upvullen van de muren 
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){//oppassen voor out of bounds

				if(actor.getXCoOrdinate()+j<ColLength && actor.getYCoOrdinate()+i<RowLength)	
					muren[3+i][3+j]=map[actor.getYCoOrdinate()+i][actor.getXCoOrdinate()+j];
				else muren[3+i][3+j]='#'; 

				if(actor.getXCoOrdinate()-j>=0 && actor.getYCoOrdinate()-i>=0)
					muren[3-i][3-j]=map[actor.getYCoOrdinate()-i][actor.getXCoOrdinate()-j];
				else muren[3-i][3-j]='#'; 

				if(actor.getXCoOrdinate()-j>=0 && actor.getYCoOrdinate()+i<RowLength)
					muren[3+i][3-j]=map[actor.getYCoOrdinate()+i][actor.getXCoOrdinate()-j];
				else muren[3+i][3-j]='#';

				if(actor.getXCoOrdinate()+j<ColLength && actor.getYCoOrdinate()-i>=0)
					muren[3-i][3+j]=map[actor.getYCoOrdinate()-i][actor.getXCoOrdinate()+j];
				else muren[3-i][3+j]='#';
			}
		}

		//optellen lege vakjes
		for(int i=0; i<7;i++){
			for(int j=0; j<7;j++){
				if(muren[i][j]=='#')
					aantalLegeVakjes++;				 
			}
		}	

		//murenCheck/(map.length*map[0].length <-- gemiddeld aantal muren op het bord
		Double extraMuren= aantalLegeVakjes*(murenCheck/(map.length*map[0].length));

		//optellen van het aantal muren
		for(int i=0; i<7;i++){
			for(int j=0; j<7;j++){
				if(muren[i][j]=='%')
					aantalmuren++;				 
			}
		}		

		final double cost = 1d;

		if(finish != null){
			Double check=cost* (Math.abs(actor.getXCoOrdinate() - finish.getXCoOrdinate()) + Math.abs(actor.getYCoOrdinate() - finish.getYCoOrdinate()));
			Double returnwaarde=check + aantalmuren + extraMuren;
			//System.out.println("heurestiekwaarde voor muren " + returnwaarde);
			return returnwaarde;
		}
		return 0;	
	}

}
